using System;
using System.Collections.Generic;

namespace Shlick
{
	public interface ICommand
	{
		string Name { get; }
		
		void Do();
		void Undo();
	}

	public class CommandManager
	{
		private Stack<ICommand> UndoStack = new Stack<ICommand>();
		private Stack<ICommand> RedoStack = new Stack<ICommand>();
	
		public CommandManager ()
		{
		}
		
		public void Do(ICommand cmd)
		{
			if (cmd == null)
				throw new Exception();
		
			RedoStack.Clear();
			cmd.Do();
			UndoStack.Push(cmd);
  		}
  		
  		
  		
  		public bool Undo()
  		{
  			ICommand cmd;
  			lock (UndoStack)
  				if (UndoStack.Count == 0)
  					return false;
  				else
  					cmd = UndoStack.Pop();
  			
  			cmd.Undo();
  			
  			lock (RedoStack)
  				RedoStack.Push(cmd);
  			return true;
  		}
  		
  		public void UndoAll()
  		{
  			lock (UndoStack)
  				while (UndoStack.Count > 0)
  					this.Undo();
  		}
  		
  		public bool Redo()
  		{
  		  	ICommand cmd;
  			lock (RedoStack)
  				if (RedoStack.Count == 0)
  					return false;
  				else
  					cmd = RedoStack.Pop();
  			
  			cmd.Do();
  			
  			lock (UndoStack)
  				UndoStack.Push(cmd);
  			return true;
  		}
  		
  		public void RedoAll()
  		{
  			lock (RedoStack)
  				while(RedoStack.Count > 0)
  					this.Redo();
  		}
	}
}

